interface NetCallback {
  successcb?: (res: any) => void
  failcb?: (res: any) => void
}
interface baseRequestInfo extends NetCallback {
  url: string
  method: 'POST' | 'GET'
  data?: any
  args?: any
}
interface baseInfo extends NetCallback { device_id: string | string[] }
interface addDeviceInfo extends NetCallback {
  data: {
    title: string//	设备名称
    desc?: string//	设备描述
    tags?: string[]//	设备标签，可为一个或者多个，见示例
    location?: {//	设备位置坐标信息，以经纬度键值对表示:{"lon":xx,"lat":xx}
      lon: number//
      lat: number//
    }
    private?: boolean//	设备私密性，决定应用编辑器分享链接中设备信息的可见度，默认为true
    auth_info?: string//	鉴权信息，建议携带，并设置为设备的产品序列号
    other?: object//	其他设备自定义信息，以键值对格式表示，见示例
  }
}
interface DeviceInfo extends baseInfo { }
interface MultipleDeviceInfo extends baseInfo {
  args?: {
    key_words?: string//	匹配关键字，从id和title字段中左匹配
    auth_info?: string//	鉴权信息
    tag?: string[]//	设备标签
    online?: boolean//设备在线状态
    private?: boolean//	设备私密性
    page?: number//	指定页码，最大页数为10000
    per_page?: number//	指定每页输出设备个数，默认30，最多100
    begin?: string//	起始时间，北京时间，示例：2016-06-20
    end?: string//	结束时间，北京时间，示例：2016-06-20
  }
}
interface DataStreamInfo extends baseInfo { dataStreamID?: string | string[] }
interface DataPointsInfo extends baseInfo {
  args?: {
    datastream_id?: string | string[] //数据流ID，多个id之间用逗号分开，缺省时为查询所有数据流
    start?: string //提取数据点的开始时间，精确到秒，示例：2015-01-10T08:00:35
    end?: string //提取数据点的结束时间，精确到秒，示例：2015-01-10T08:00:35
    duration?: number //查询时间区间，单位为秒
    limit?: number //限定本次请求最多返回的数据点数，默认100，范围为(0,6000]
    cursor?: string  //指定本次请求继续从cursor位置开始提取数据
    sort?: 'ASC' | 'DESC'  //时间排序方式，DESC：倒序，ASC：升序，默认为ASC
  }
}
interface CommandInfo extends baseInfo {
  command?: any
  commandID?: string
  args?: {
    qos?: 0 | 1
    timeout?: number
  }
}

function getUrlArgsFromObj(obj: any) {
  var urlArgs = '?'
  for (let i in obj) {
    urlArgs += i + '=' + obj[i] + '&'
  }
  return urlArgs == '?' ? '' : urlArgs.substr(0, urlArgs.length - 1)
}

class OneNETAPI {
  APIKEY: string
  constructor(Key: string) {//构造器初始化APIKey
    this.APIKEY = Key
  }
  defaultNetworkcb(res: any) {//用户未设置网络请求回调函数时的默认回调
    console.log(res)
  }
  baseRequest(info: baseRequestInfo) {//封装底层接口
    if (info.successcb == null)
      info.successcb = this.defaultNetworkcb
    if (info.failcb == null)
      info.failcb = this.defaultNetworkcb
    wx.request({
      url: 'https://api.heclouds.com' + info.url + getUrlArgsFromObj(info.args),
      data: info.data,//请求数据
      dataType: "json",
      fail: (res) => {//失败回调
        info.failcb!(res)
      },
      header: { 'api-key': this.APIKEY },
      method: info.method,//请求方法
      success: (res) => {//成功回调
        info.successcb!(res.data)
      },
    })
  }
  addDevice(info: addDeviceInfo) {//新增设备
    this.baseRequest({
      url: '/devices',
      method: 'POST',
      data: info.data,
      failcb: info.failcb,//失败回调
      successcb: info.successcb//成功回调
    })
  }
  getDevice(info: DeviceInfo) {//查询设备信息
    if (info.device_id == '') {//设备ID不能为空
      console.error('输入到getDevice中的deviceID不能为空')
      return
    }
    this.baseRequest({
      url: '/devices/' + info.device_id,
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getDevices(info: MultipleDeviceInfo) {//批量查询设备信息
    var args: any = info.args
    if (args)
      args.device_id = info.device_id
    this.baseRequest({
      url: '/devices',
      method: 'GET',
      args: args,
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getDevicesStatus(info: DeviceInfo) {//批量查询设备在线情况
    this.baseRequest({
      url: '/devices/status',
      method: 'GET',
      args: { devIds: info.device_id },
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  deleteDevice(info: DeviceInfo) {//删除设备
    if (info.device_id == '') {
      console.error('输入到deleteDevice中的deviceID不能为空')
      return
    }
    this.baseRequest({
      url: '/devices/' + info.device_id,
      method: 'POST',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getDataStream(info: DataStreamInfo) {//查询设备数据流,单个设备单个数据流
    if (info.device_id == '') {
      console.error('输入到getDataStream中的deviceID不能为空')
      return
    }
    if (info.dataStreamID == '') {
      console.error('输入到getDataStream中的dataStreamID不能为空')
      return
    }
    this.baseRequest({
      url: '/devices/' + info.device_id + '/datastreams/' + info.dataStreamID,
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getDataStreams(info: DataStreamInfo) {//批量查询设备数据流,单个设备多个数据流
    let _dataStreamsID: string = ''
    if (info.device_id == '') {
      console.error('输入到getDataStreams中的deviceID不能为空')
      return
    }
    if (info.dataStreamID != null) {//输入数据流不为空时
      _dataStreamsID = '/'
      for (let item of info.dataStreamID) {
        _dataStreamsID += item + ','////将string array转为逗号分隔的字符串
      }
    }
    this.baseRequest({
      url: '/devices/' + info.device_id + '/datastreams' + _dataStreamsID,
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getDataPoints(info: DataPointsInfo) { // 获取历史数据
    if (info.device_id == '') {
      console.error('输入到getDataStreams中的deviceID不能为空')
      return
    }
    this.baseRequest({
      url: '/devices/' + info.device_id + '/datapoints',
      args: info.args,
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  sendCommand(info: CommandInfo) {//发送命令
    if (info.device_id == '') {
      console.error('输入到sendCommand中的deviceID不能为空')
      return
    }
    info.args!['device_id'] = info.device_id
    this.baseRequest({
      url: '/cmds',
      args: info.args,
      method: 'POST',
      data: info.command,
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getCommandStatus(info: CommandInfo) {//查询命令状态
    if (info.commandID == '') {
      console.error('输入到getCommandStatus中的commandID不能为空')
    }
    this.baseRequest({
      url: '/cmds/' + info.commandID,
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
  getCommandRespond(info: CommandInfo) {//查询命令响应内容
    if (info.commandID == '') {
      console.error('输入到getCommandRespond中的commandID不能为空')
      return
    }
    this.baseRequest({
      url: '/cmds/' + info.commandID + '/resp',
      method: 'GET',
      successcb: info.successcb,
      failcb: info.failcb
    })
  }
}
export { OneNETAPI }